package com.jiandan.plugin.module

import com.alibaba.ocean.rawsdk.ApiExecutor
import com.alibaba.ocean.rawsdk.client.exception.OceanException
import com.umeng.uapm.param.UmengQuickbirdSymUploadParam
import com.umeng.uapm.param.UmengQuickbirdSymUploadResult
import javax.activation.MimetypesFileTypeMap
import java.util.Map.Entry

class UmengUpload {


    /**
     * 上传文件
     */
    void upload(String filePath, String apiKey, String secKey, String appKey, String appVersion) {
        println("混淆文件上传 开始...")
        UmengQuickbirdSymUploadResult result = getUploadParam(apiKey, secKey, appKey, appVersion)
        if (result == null) {
            return
        }
        uploadFile(filePath, result)
    }

    private UmengQuickbirdSymUploadResult getUploadParam(String apiKey, String secKey, String appKey, String appVersion) {
        ApiExecutor apiExecutor = new ApiExecutor(apiKey, secKey)
        apiExecutor.setServerHost("gateway.open.umeng.com")
        UmengQuickbirdSymUploadParam param = new UmengQuickbirdSymUploadParam()
        param.setDataSourceId(appKey)
        param.setAppVersion(appVersion)
        param.setFileType(1)
        param.setFileName("mapping.txt")
        try {
            UmengQuickbirdSymUploadResult result = apiExecutor.execute(param)
            return result
        } catch (OceanException e) {
            println("混淆文件上传参数 获取失败:errorCode=" + e.getErrorCode() + ", errorMessage=" + e.getErrorMessage())
        }
        return null
    }

    private void uploadFile(String filePath, UmengQuickbirdSymUploadResult result) {
        String uploadAddress = result.uploadAddress
        Map<String, String> formFields = new HashMap<>()
        formFields.put("OSSAccessKeyId", result.accessKeyId)
        formFields.put("key", result.key)
        formFields.put("policy", result.policy)
        formFields.put("signature", result.signature)
        formFields.put("callback", result.callback)
        String res = formUpload(uploadAddress, formFields, filePath)
        println("混淆文件上传result: " + res)
    }

    private static String formUpload(String urlStr, Map<String, String> formFields, String localFile) {
        String res = ""
        HttpURLConnection conn = null
        String boundary = "9431149156168"
        try {
            URL url = new URL(urlStr)
            conn = (HttpURLConnection) url.openConnection()
            conn.setConnectTimeout(5000)
            conn.setReadTimeout(30000)
            conn.setDoOutput(true)
            conn.setDoInput(true)
            conn.setRequestMethod("POST")
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)")
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + boundary)
            OutputStream out = new DataOutputStream(conn.getOutputStream())
            // 遍历读取表单Map中的数据，将数据写入到输出流中。
            if (formFields != null) {
                StringBuffer strBuf = new StringBuffer()
                Iterator<Entry<String, String>> iter = formFields.entrySet().iterator()
                int i = 0
                while (iter.hasNext()) {
                    Entry<String, String> entry = iter.next()
                    String inputName = entry.getKey()
                    String inputValue = entry.getValue()
                    if (inputValue == null) {
                        continue
                    }
                    if (i == 0) {
                        strBuf.append("--").append(boundary).append("\r\n")
                        strBuf.append("Content-Disposition: form-data; name=\""
                                + inputName + "\"\r\n\r\n")
                        strBuf.append(inputValue)
                    } else {
                        strBuf.append("\r\n").append("--").append(boundary).append("\r\n")
                        strBuf.append("Content-Disposition: form-data; name=\""
                                + inputName + "\"\r\n\r\n")
                        strBuf.append(inputValue)
                    }
                    i++
                }
                out.write(strBuf.toString().getBytes())
            }
            // 读取文件信息，将要上传的文件写入到输出流中。
            File file = new File(localFile)
            String filename = file.getName()
            String contentType = new MimetypesFileTypeMap().getContentType(file)
            if (contentType == null || contentType.equals("")) {
                contentType = "application/octet-stream"
            }
            StringBuffer strBuf = new StringBuffer()
            strBuf.append("\r\n").append("--").append(boundary)
                    .append("\r\n")
            strBuf.append("Content-Disposition: form-data; name=\"file\"; "
                    + "filename=\"" + filename + "\"\r\n")
            strBuf.append("Content-Type: " + contentType + "\r\n\r\n")
            out.write(strBuf.toString().getBytes())
            long total = file.length()
            long writeLength = 0
            def lastResult = 0
            DataInputStream inputStream = new DataInputStream(new FileInputStream(file))
            int bytes
            byte[] bufferOut = new byte[1024]
            while ((bytes = inputStream.read(bufferOut)) != -1) {
                writeLength = writeLength + bytes
                out.write(bufferOut, 0, bytes)
                double progress = writeLength * 100.0 / total
                def progressInt = progress.toInteger()
                if (lastResult != progressInt) {
                    lastResult = progressInt
                    println("混淆文件上传进度：" + progressInt + "%")
                }
            }
            inputStream.close()
            byte[] endData = ("\r\n--" + boundary + "--\r\n").getBytes();
            out.write(endData)
            out.flush()
            out.close()
            // 读取返回数据。
            strBuf = new StringBuffer();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line
            while ((line = reader.readLine()) != null) {
                strBuf.append(line).append("\n")
            }
            res = strBuf.toString()
            reader.close()
        } catch (Exception e) {
            System.err.println("Send post request exception: " + e)
            throw e
        } finally {
            if (conn != null) {
                conn.disconnect()
            }
        }
        return res
    }
}
